const CacheConstant = require('../constant/cache')
const { USER_AGENT } = require('../constant/rest')
const ApiRes = require('../lib/utils/api-res')
const PasswordIdentifierDTO = require('../dto/password-identifier')
const AuthenticationService = require('../services/authentication')
const Ip2regionService = require('../services/ip2region')
const { getClientIpAndPort } = require('../lib/utils/ip')
const RouteService = require('../services/route')
const RoleService = require('../services/role')

async function login(ctx) {
  const { ip, port } = getClientIpAndPort(ctx.request)
  const data = ctx.request.body
  let region = 'Unknown'

  // try {
  //   const ip2regionResult = await Ip2regionService.getSearcher().search(ip)
  //   region = ip2regionResult.region || region
  // } catch (_) {
  //   // console.log(_)
  //   // TODO: 无法获取准确的地理位置信息
  // }

  const token = await AuthenticationService.execPasswordLogin(
    new PasswordIdentifierDTO(data.identifier, data.password, ip, region, ctx.request.headers[USER_AGENT] ?? '', 'TODO', 'PC', port)
  )

  ctx.body = ApiRes.success(token)
}

async function refreshToken(refreshToken, request) {
  const { ip, port } = getClientIpAndPort(request)
  let region = 'Unknown'

  try {
    const ip2regionResult = await Ip2regionService.getSearcher().search(ip)
    region = ip2regionResult.region || region
  } catch (_) {}
  const token = await this.authenticationService.refreshToken(refreshToken, ip, region, request.headers[USER_AGENT] ?? '', 'TODO', 'PC', port)
  return ApiRes.success(token)
}

async function getProfile(ctx) {
  const { user } = ctx.state

  const userInfo = await AuthenticationService.getProfile(user.uid)
  // 查询从用户信息
  ctx.body = ApiRes.success(userInfo)
}

async function getUserRoutes(ctx) {
  const { uid } = ctx.state.user
  const routes = await RouteService.getUserRoutes(uid)
  ctx.body = ApiRes.success(routes)
}

// 角色分配路由
async function assignRoutes(ctx) {
  const { roleId, routeIds } = ctx.request.body
  const finalRouteIds = routeIds.split(',').map((id) => parseInt(id))
  const existsRoutes = await RoleService.findRouteIdWithRoleId(roleId)

  const needAddRoutes = finalRouteIds.filter((routeId) => !existsRoutes.includes(routeId))
  const needDeleteRoutes = existsRoutes.filter((routeId) => !finalRouteIds.includes(routeId))

  if (needAddRoutes.length) {
    await RoleService.addManyMenuWithRole(roleId, needAddRoutes)
  }

  if (needDeleteRoutes.length) {
    await RoleService.deleteManyMenuWithRole(roleId, needDeleteRoutes)
  }

  ctx.body = ApiRes.ok()
}

// 角色分配用户
async function assignUsers(ctx) {
  const { roleId, userIds } = ctx.request.body
  const finalUserIds = userIds.split(',')
  const existsUsers = await RoleService.findUserIdWithRoleId(roleId)

  const needAddUsers = finalUserIds.filter((userId) => !existsUsers.includes(userId))
  const needDeleteUsers = existsUsers.filter((userId) => !finalUserIds.includes(userId))

  if (needAddUsers.length) {
    await RoleService.addManyUserWithRole(roleId, needAddUsers)
  }

  if (needDeleteUsers.length) {
    await RoleService.deleteManyUserWithRole(roleId, needDeleteUsers)
  }

  ctx.body = ApiRes.ok()
}

module.exports = {
  login,
  refreshToken,
  getProfile,
  getUserRoutes,
  assignRoutes,
  assignUsers
}
